#include "keyboard.h"
#include "status.h"
#include "task/process.h"
#include "task/task.h"

#include <stddef.h>

static struct keyboard* keyboard_list_head;
static struct keyboard* keyboard_list_tail;

void keyboard_init()
{

}

const int keyboard_insert(struct keyboard* keyboard)
{
    int res = 0; 
    if (!keyboard->init) {
        res = -TESTOS_STATUS_INVALID_ARG; 
        goto out; 
    }

    if (keyboard_list_tail) {
        keyboard_list_tail->next = keyboard; 
        keyboard_list_tail = keyboard; 
    }
    else {
        keyboard_list_head = keyboard;
        keyboard_list_tail = keyboard; 
    }

    res = keyboard->init(); 

out:
    return res; 
}

static const int keyboard_get_tail_index(struct process* process)
{
    return process->keyboard.tail % sizeof(process->keyboard.buffer); 
}

static const int keyboard_get_head_index(struct process* process)
{
    return process->keyboard.head % sizeof(process->keyboard.buffer); 
}

void keyboard_backspace(struct process* process)
{
    process->keyboard.tail--; 
    const int real_index = keyboard_get_tail_index(process); 
    process->keyboard.buffer[real_index] = 0x00; 
}

void keyboard_push(const char c) 
{
    struct process* process = get_current_process(); 
    if (!process) {
        return; 
    }

    const int real_index = keyboard_get_tail_index(process);
    process->keyboard.buffer[real_index] = c; 
    process->keyboard.tail++; 
}

const char keyboard_pop()
{
    struct task* current_task = get_current_task(); 
    if (!current_task) {
        return 0; 
    }

    struct process* process = current_task->process; 
    const int real_index = keyboard_get_head_index(process); 
    const char c = process->keyboard.buffer[real_index]; 
    if (c == 0) {
        // nothing to pop
        return 0; 
    }

    process->keyboard.buffer[real_index] = 0; 
    process->keyboard.head++;
    return c; 
}